package View.CoolSwing;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import org.jdesktop.animation.timing.*;

/**
 * @author Shannon Hickey
 */
public class CoolButton extends JButton implements TimingTarget {
    private static boolean REPAINT_SHADOW = true;
    
    private static final Color COLOR1 = new Color(125, 161, 237);
    private static final Color COLOR2 = new Color(91, 118, 173);
    
    private int style;
    private float pct;
    private boolean forward;
    
    private Animator cont = new Animator(200, this);

    /**
     * 鼠标监听器，鼠标进入和出去时改变样式
     */
    private final MouseAdapter MLISTENER = new MouseAdapter() {
        public void mouseEntered(MouseEvent me) {
            cont.stop();
            forward = true;
            cont.start();
        }
        
        public void mouseExited(MouseEvent me) {
            cont.stop();
            forward = false;
            cont.start();
        }
    };

    /**
     * TimingTarget的begin方法实现
     */
    public void begin() {
    }
    
    /**
     * TimingTarget的end方法实现
     */
    public void end() {
        if (forward) {
            setForeground(Color.WHITE);
            pct = 1.0f;
        } else {
            setForeground(COLOR2);
            pct = 0.0f;
        }
        Container p = getParent();
        if (p instanceof DropShadowPanel && REPAINT_SHADOW) {
            ((DropShadowPanel)p).propertyChange(null);
        } else {
            repaint();
        }
    }
    
    /**
     * TimingTarget的timingEvent方法实现
     */
    public void timingEvent(float fraction) {
        if (forward) {
            pct = fraction;
            int r = COLOR2.getRed() + (int) ((Color.WHITE.getRed() - COLOR2.getRed()) * pct);
            int g = COLOR2.getGreen() + (int) ((Color.WHITE.getGreen() - COLOR2.getGreen()) * pct);
            int b = COLOR2.getBlue() + (int) ((Color.WHITE.getBlue() - COLOR2.getBlue()) * pct);
            setForeground(new Color(r, g, b));
        } else {
            pct = 1.0f - fraction;
            int r = COLOR2.getRed() + (int) ((Color.WHITE.getRed() - COLOR2.getRed()) * pct);
            int g = COLOR2.getGreen() + (int) ((Color.WHITE.getGreen() - COLOR2.getGreen()) * pct);
            int b = COLOR2.getBlue() + (int) ((Color.WHITE.getBlue() - COLOR2.getBlue()) * pct);
            setForeground(new Color(r, g, b));
        }
        Container p = getParent();
        if (p instanceof DropShadowPanel && REPAINT_SHADOW) {
            ((DropShadowPanel)p).propertyChange(null);
        } else {
             //repaint();
        }
    }
    
	@Override
	public void repeat() {
		
	}

//	@Override
//	public void timingEvent(float arg0) {
//		
//	}
	
    /**
     * 构造方法
     */
    public CoolButton() {
    	this(0);
    }
    
    /**
     * 构造方法
     * @param style
     */
    public CoolButton(int style) {
        super();
        this.style = style;
        setContentAreaFilled(false);
        setBorderPainted(false);
        setForeground(COLOR2);
        addMouseListener(MLISTENER);
        //setFont(getFont().deriveFont(Font.BOLD));
    }
    
    /**
     * 重写绘制组建方法
     */
    public void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D)g.create();
        
        int h = getHeight();
        int w = getWidth();
        
        float tran = 0.1f + pct * 0.9f;
        
        GradientPaint GP = new GradientPaint(0, 0, COLOR1, 0, h, COLOR2, true);
        g2d.setPaint(GP);
        

        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        GradientPaint p1;
        GradientPaint p2;
        
        if (getModel().isPressed()) {
            p1 = new GradientPaint(0, 0, new Color(0, 0, 0), 0, h - 1, new Color(100, 100, 100));
            p2 = new GradientPaint(0, 1, new Color(0, 0, 0, 50), 0, h - 3, new Color(255, 255, 255, 100));
        } else {
            p1 = new GradientPaint(0, 0, new Color(100, 100, 100), 0, h - 1, new Color(0, 0, 0));
            p2 = new GradientPaint(0, 1, new Color(255, 255, 255, 100), 0, h - 3, new Color(0, 0, 0, 50));
        }
        
        if (style == 0) {
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tran));
            RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, 0, w - 1, h - 1, 20, 20);
            Shape clip = g2d.getClip();
            g2d.clip(r2d);
            g2d.fillRect(0, 0, w, h);
            g2d.setClip(clip);
            g2d.setPaint(p1);
            g2d.drawRoundRect(0, 0, w - 1, h - 1, 20, 20);
            g2d.setPaint(p2);
            g2d.drawRoundRect(1, 1, w - 3, h - 3, 18, 18);
            g2d.dispose();
        } else if (style == 1) {
            RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(0, 0, w - 1 + 20, h - 1, 20, 20);
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tran));
            Shape clip = g2d.getClip();
            g2d.clip(r2d);
            g2d.fillRect(0, 0, w, h);
            g2d.setClip(clip);
            g2d.setPaint(p1);
            g2d.drawRoundRect(0, 0, w - 1 + 20, h - 1, 20, 20);
            g2d.setPaint(p2);
            g2d.drawRoundRect(1, 1, w - 3 + 20, h - 3, 18, 18);
            g2d.setPaint(p1);
            g2d.drawLine(w - 1, 1, w - 1, h);
            g2d.setPaint(p2);
            g2d.drawLine(w - 2, 2, w - 2, h - 1);
            g2d.dispose();
        } else if (style == 2) {
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tran));
            g2d.fillRect(0, 0, w, h);
            g2d.setPaint(p1);
            g2d.drawRect(-5, 0, w - 1 + 10, h - 1);
            g2d.setPaint(p2);
            g2d.drawRect(-5, 1, w - 3 + 10, h - 3);
            g2d.setPaint(p1);
            g2d.drawLine(0, 0, 0, h);
            g2d.drawLine(w - 1, 1, w - 1, h);
            g2d.setPaint(p2);
            g2d.drawLine(1, 2, 1, h);
            g2d.drawLine(w - 2, 2, w - 2, h - 1);
            g2d.dispose();
        } else if (style == 3) {
            g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, tran));
            RoundRectangle2D.Float r2d = new RoundRectangle2D.Float(-20, 0, w - 1 + 20, h - 1, 20, 20);
            Shape clip = g2d.getClip();
            g2d.clip(r2d);
            g2d.fillRect(0, 0, w, h);
            g2d.setClip(clip);
            g2d.setPaint(p1);
            g2d.drawRoundRect(-20, 0, w - 1 + 20, h - 1, 20, 20);
            g2d.setPaint(p2);
            g2d.drawRoundRect(1 - 20, 1, w - 3 + 20, h - 3, 18, 18);
            g2d.setPaint(p1);
            g2d.drawLine(0, 1, 0, h);
            g2d.setPaint(p2);
            g2d.drawLine(1, 2, 1, h - 1);
            g2d.dispose();
        } 
        super.paintComponent(g);
    }
}
